<script lang="ts" setup>
import dayjs from 'dayjs'
import {
    Button,
    DatePicker,
    Divider,
    Dropdown,
    Form,
    Input,
    Menu,
    Modal,
    Popconfirm,
    Table,
    message,
    Checkbox,
    TimePicker
} from 'ant-design-vue'
import { type AfterFetchContext, objectOmit } from '@vueuse/core'
import type { IBasic, IBasicWithPage } from '~/types/apis/basic'
import type { ITimePlan } from '~/types/apis/time-plan'
import type { ColumnsType } from 'ant-design-vue/es/table'
import { Select, Tooltip } from 'ant-design-vue'
import type { IModule } from '~/types/apis/module'
import type { ICaseID } from '~/types/apis/case_id'
import utc from 'dayjs/plugin/utc' // 导入 UTC 插件
import timezone from 'dayjs/plugin/timezone' // 导入时区


const searchParams = reactive<{
    page: number
    size: number
    projectId: number | undefined
    name: string | undefined
}>({
    page: 1,
    size: 8,
    projectId: undefined,
    name: undefined,
    totalSize: 0,
})

const testTypeList = reactive<{
    id: number
    type: string
}>([
    {
        id: 1,
        type: 'STRESS',
    },
    {
        id: 2,
        type: 'API',
    },
    {
        id: 3,
        type: 'UI',
    }, {
        id: 4,
        type: 'MIX',
    },
])

const columns: ColumnsType = [
    {
        title: 'ID',
        dataIndex: 'id',
        key: 'id',
        align: 'center',
    },
    {
        title: '名称',
        dataIndex: 'name',
        key: 'name',
        align: 'center',
    },
    {
        title: '用例类型',
        dataIndex: 'testType',
        key: 'testType',
        align: 'center',
    },
    {
        title: '用例 ID',
        dataIndex: 'caseId',
        key: 'caseId',
        align: 'center',
    },
    {
        title: '环境 ID',
        dataIndex: 'environmentId',
        key: 'environmentId',
        align: 'center',
    },
    {
        title: '执行时间',
        dataIndex: 'executeTime',
        key: 'executeTime',
        align: 'center',
    },
    {
        title: '状态',
        dataIndex: 'isDisabled',
        key: 'isDisabled',
        align: 'center',
    },
    {
        key: 'operator',
        dataIndex: 'operator',
        title: '操作',
        align: 'center',
    },
]

const globalConfigStore = useGlobalConfigStore()

// 模板列表
let modules = ref([])
// 用例ID列表
let caseIds = ref([])
// 新增表单Ref
const formAddRef = ref();
const formUpdateRef = ref();
// 表单校验
const formRules = {
    name: [
        { required: true, message: '请输入名称', trigger: 'blur' },
    ],
    testType: [
        { required: true, message: '请选择用例类型', trigger: 'blur' },
    ],
    caseId: [
        { required: true, message: '请选择用例ID', trigger: 'blur' },
    ],
    environmentId: [
        { required: true, message: '请选择环境', trigger: 'blur' },
    ],
    executeTime: [
        { required: true, message: '请选择执行时间', trigger: 'blur' },
    ],
    isDisabled: [
        { required: true, message: '请选择状态', trigger: 'blur' },
    ],

}

const {
    post: executeGetTestPage,
    data: dataSource,
    isFetching,
} = useCustomFetch<ITimePlan[]>('/engine-service/api/v1/plan_job/page', {
    immediate: false,
    initialData: [],
    afterFetch: (ctx: AfterFetchContext<IBasicWithPage<ITimePlan[]>>) => {
        if (ctx.data && ctx.data.code === 0) {
            const currentTime = Date.now();
            ctx.data.data.current_data.forEach((element: ITimePlan) => {
                if (element.executeInterval === 'EVERYDAY') {
                    element.executeInterval = true
                } else {
                    element.executeInterval = false
                }
            });
            searchParams.totalSize = ctx.data.data.total_record
            return {
                data: ctx.data.data.current_data,
                response: ctx.response,
            }
        }
        return {
            data: [],
            response: ctx.response,
        }
    },
})

async function reFetch() {
    await nextTick()
    executeGetTestPage(toRaw(searchParams)).execute()
}

//删除
const { post: executeDeleteReport } = useCustomFetch<ITimePlan[]>(
    '/engine-service/api/v1/plan_job/del',
    {
        immediate: false,
        initialData: [],
        afterFetch: (ctx: AfterFetchContext<IBasicWithPage<ITimePlan>>) => {
            if (ctx.data && ctx.data.code === 0) {
                message.success(ctx.data.msg ?? '删除成功！')
            }
            return ctx
        },
    },
)

async function handleDelete(record: ITimePlan) {
    await executeDeleteReport({
        id: record.id,
        projectId: record.projectId,
    }).execute()
    reFetch()
}

//编辑
const openUpdate = ref<boolean>(false)
const oneUpdateValue = reactive<ITimePlan>({
    id: null,
    projectId: null,
    environmentId: null,
    executeTime: undefined,
    gmtModified: '',
    gmtCreate: '',
    name: '',
    caseId: null,
    testType: '',
    isDisabled: null,
    moduleId: null,
    executeInterval: false,
})
const handleUpdateSelectTypeList = (type: string) => {
    if (modules.value.length > 0) {
        modules.value = []
        oneUpdateValue.moduleId = null
    }
    if (caseIds.value.length > 0) {
        caseIds.value = []
        oneUpdateValue.caseId = null
    }

    oneUpdateValue.testType = type
}

const toggleDisabledStatus = () => {
    oneUpdateValue.isDisabled = oneUpdateValue.isDisabled === 0 ? 1 : 0
}
function formatToCustomFormat(dateString) {
    return dayjs(dateString)
}

const handleOpenUpdate = (updateValue: ITimePlan) => {
    const { executeTime, ...rest } = updateValue
    oneUpdateValue.executeTime = executeTime
    Object.assign(oneUpdateValue, rest)
    openUpdate.value = true
    fetchCaseIds2()
    fetchModules2()
}
const { post: handleUpdateValue } = useCustomFetch<ITimePlan[]>(
    '/engine-service/api/v1/plan_job/update',
    {
        immediate: false,
        afterFetch: (ctx: AfterFetchContext<IBasicWithPage<ITimePlan>>) => {
            if (ctx.data && ctx.data.code === 0) {
                message.success(ctx.data.msg ?? '修改成功！')
                reFetch()
            }
            return ctx
        },
    },
)

const handleUpdate = async () => {
    formUpdateRef.value
        .validate()
        .then(async () => {
            // dayjs.extend(utc)
            // dayjs.extend(timezone)
            // const dateStr = oneUpdateValue.executeTime
            // oneUpdateValue.executeTime = dayjs.utc(dateStr).tz('Asia/Shanghai').format('YYYY-MM-DD HH:mm:ss')
            // if (oneUpdateValue.executeInterval && oneUpdateValue.executeTime.includes(' ')) {
            //     oneUpdateValue.executeTime = oneUpdateValue.executeTime.split(' ')[1]
            // }
            oneUpdateValue.executeInterval = oneUpdateValue.executeInterval ? 'EVERYDAY' : 'ONCE'
            await handleUpdateValue(toRaw(oneUpdateValue)).execute()
            openUpdate.value = false
        })
}

//新增
const openAdd = ref<boolean>(false)
const oneAddValue = reactive<ITimePlan>({
    id: null,
    projectId: null,
    environmentId: null,
    executeTime: '',
    gmtModified: '',
    gmtCreate: '',
    name: '',
    caseId: null,
    testType: '',
    isDisabled: 1,
    moduleId: null,
    executeInterval: false
})

const handleSelectTypeList = (type: string) => {
    if (modules.value.length > 0) {
        modules.value = []
        oneAddValue.moduleId = null
    }
    if (caseIds.value.length > 0) {
        caseIds.value = []
        oneAddValue.caseId = null
    }
    oneAddValue.testType = type
}

const handleChange = (value: number) => {
    oneAddValue.environmentId = value
};
const cancelClick = () => {
    // oneAddValue.id = null
    // oneAddValue.projectId = null
    // oneAddValue.executeTime = ''
    // oneAddValue.gmtModified = ''
    // oneAddValue.gmtCreate = ''
    // oneAddValue.name = ''
    oneAddValue.caseId = null
    // oneAddValue.testType = ''
    // oneAddValue.isDisabled = 1
    oneAddValue.moduleId = null
    formAddRef.value.resetFields();
}

const AddTestPlan = () => {
    openAdd.value = true
}
const toggleADDDisabledStatus = () => {
    oneAddValue.isDisabled = oneAddValue.isDisabled === 0 ? 1 : 0
}
const { post: handleAddValue } = useCustomFetch<ITimePlan[]>(
    '/engine-service/api/v1/plan_job/save',
    {
        immediate: false,
        afterFetch: (ctx: AfterFetchContext<IBasicWithPage<ITimePlan>>) => {
            if (ctx.data && ctx.data.code === 0) {
                message.success(ctx.data.msg ?? '新增成功！')
                reFetch()
            }
            return ctx
        },
    },
)

const handleAdd = () => {
    formAddRef.value
        .validate()
        .then(async () => {
            oneAddValue.executeInterval = oneAddValue.executeInterval ? 'EVERYDAY' : 'ONCE'
            await handleAddValue(toRaw(oneAddValue)).execute()
            // oneAddValue.id = null
            // oneAddValue.projectId = null
            // oneAddValue.environmentId = null
            // oneAddValue.executeTime = ''
            // oneAddValue.gmtModified = ''
            // oneAddValue.gmtCreate = ''
            // oneAddValue.name = ''
            // oneAddValue.caseId = null
            // oneAddValue.testType = ''
            // oneAddValue.isDisabled = 1
            oneAddValue.moduleId = null
            formAddRef.value.resetFields();
            openAdd.value = false
        })
        .catch((error: ValidateErrorEntity<FormState>) => {
            console.log('error', error);
        });



}

// 动态获取模板列表的api
const modulesUrl = computed(
    () => `/engine-service/api/v1/${oneAddValue.testType.toLowerCase()}_case_module/list`,
)

// 获取module列表
const { execute: fetchModules } = useCustomFetch<IModule[]>(
    modulesUrl,
    {
        immediate: false,
        afterFetch: (ctx: AfterFetchContext<IBasicWithPage<ITimePlan>>) => {
            if (ctx.data && ctx.data.data.length > 0) {
                modules.value = ctx.data.data
            } else {
                console.info(`未查到数据`)
            }
            return ctx
        },
    },
)


// 动态获取模板列表的api
const modulesUrl2 = computed(
    () => `/engine-service/api/v1/${oneUpdateValue.testType.toLowerCase()}_case_module/list`,
)

// 获取module列表
const { execute: fetchModules2 } = useCustomFetch<IModule[]>(
    modulesUrl2,
    {
        immediate: false,
        afterFetch: (ctx: AfterFetchContext<IBasicWithPage<ITimePlan>>) => {
            if (ctx.data && ctx.data.data.length > 0) {
                modules.value = ctx.data.data
            } else {
                console.info(`未查到数据`)
            }
            return ctx
        },
    },
)

// 点击模块 type: 0-模板 1-用例id
const handleFocus = async (type: number) => {
    if (oneAddValue.testType === '' && oneAddValue.testType.length == 0) {
        return message.warning('请选择用例类型！');
    }
    // 为防止用户选择了id后又重选模块导致模块与id不一致 所以需要重置用例id
    if (type === 0) {
        oneAddValue.caseId = null
    }
    type == 0 ? await fetchModules() : await fetchCaseIds()
}

const handleUpdateFocus = async (type: number) => {
    if (oneUpdateValue.testType === '' && oneUpdateValue.testType.length == 0) {
        return message.warning('请选择用例类型！');
    }
    // 为防止用户选择了id后又重选模块导致模块与id不一致 所以需要重置用例id
    if (type === 0) {
        oneUpdateValue.caseId = null
    }
    type == 0 ? await fetchModules2() : await fetchCaseIds2()
}


// 动态获取用例id列表的api
const caseIdsUrl = computed(
    () => {
        if (oneAddValue.moduleId === null) {
            return `/engine-service/api/v1/${oneAddValue.testType.toLowerCase()}_case/list`
        } else {
            return `/engine-service/api/v1/${oneAddValue.testType.toLowerCase()}_case/list?moduleId=${oneAddValue.moduleId}`
        }
    },
)
// 获取用例ID列表
const { execute: fetchCaseIds } = useCustomFetch<ICaseID[]>(
    caseIdsUrl,
    {
        immediate: false,
        afterFetch: (ctx: AfterFetchContext<IBasicWithPage<ITimePlan>>) => {
            if (ctx.data && ctx.data.data.length > 0) {
                caseIds.value = ctx.data.data
            } else {
                console.info(`未查到数据`)
            }
            return ctx
        },
    },
)

// 动态获取用例id列表的api
const caseIdsUrl2 = computed(
    () => {
        if (oneUpdateValue.moduleId === '') {
            return `/engine-service/api/v1/${oneUpdateValue.testType.toLowerCase()}_case/list`
        } else {
            return `/engine-service/api/v1/${oneUpdateValue.testType.toLowerCase()}_case/list?moduleId=${oneUpdateValue.moduleId}`
        }
    },
)
// 获取用例ID列表
const { execute: fetchCaseIds2 } = useCustomFetch<ICaseID[]>(
    caseIdsUrl2,
    {
        immediate: false,
        afterFetch: (ctx: AfterFetchContext<IBasicWithPage<ITimePlan>>) => {
            if (ctx.data && ctx.data.data.length > 0) {
                caseIds.value = ctx.data.data
            } else {
                console.info(`未查到数据`)
            }
            return ctx
        },
    },
)


// 选择模块
const handleModuleChange = (value: number) => {
    oneAddValue.moduleId = value
}

// 选择用例ID
const handleCaseIDChange = (value: number) => {
    oneAddValue.caseId = value
}



// 选择模块
const handleUpdateModuleChange = (value: number) => {
    oneUpdateValue.moduleId = value
}

// 选择用例ID
const handleUpdateCaseIDChange = (value: number) => {
    oneUpdateValue.caseId = value
}

const handleAddExecuteIntervalChange = (value: any) => {
    if (!oneAddValue.executeInterval && oneAddValue.executeTime) {
        const currentTime = Date.now()
        oneAddValue.executeTime = dayjs(currentTime).format('YYYY-MM-DD HH:mm:ss').split(' ')[0] + ' ' + oneAddValue.executeTime
    } else if (oneAddValue.executeTime.includes(' ')) {
        oneAddValue.executeTime = oneAddValue.executeTime.split(' ')[1]
    }
}

const handleUpdateExecuteIntervalChange = (value: any) => {
    if (!oneUpdateValue.executeInterval && oneUpdateValue.executeTime ) {
        const currentTime = Date.now()
        const executeTime = oneUpdateValue?.executeTime.includes(":") ? oneUpdateValue.executeTime : dayjs(oneUpdateValue.executeTime).format('HH:mm:ss')
        if(!oneUpdateValue?.executeTime.includes(" ")){
            const dateStr = dayjs(currentTime).format('YYYY-MM-DD HH:mm:ss').split(' ')[0] + ' ' + executeTime
            oneUpdateValue.executeTime = dateStr
        }
    } else if (oneUpdateValue.executeTime.includes(' ')) {
        const executeTime = oneUpdateValue.executeTime.split(' ')[1]
        oneUpdateValue.executeTime = executeTime.includes(":") ? executeTime : dayjs(oneUpdateValue.executeTime).format('HH:mm:ss')
    }

}

watchImmediate(
    () => globalConfigStore.config.projectId,
    () => {
        if (globalConfigStore.config.projectId === -1) {
            return
        }
        searchParams.page = 1
        searchParams.projectId = globalConfigStore.config.projectId
        // reFetch()
    },
)
onMounted(() => {
    reFetch()
})
</script>

<template>
    <div>
        <div flex="~ justify-between">
            <div flex="~ justify-between" style="width: 300px">
                <Form.Item label="名称">
                    <Input v-model:value="searchParams.name" placeholder="无" style="width: 180px"
                        @keyup.enter="reFetch()" />
                </Form.Item>
                <Form.Item>
                    <Button type="primary" @click="reFetch()"> 搜索 </Button>
                </Form.Item>
            </div>
        </div>
        <Table :loading="isFetching" :data-source="dataSource!" :columns="columns" :pagination="{
            showLessItems: true,
            current: searchParams.page,
            pageSize: searchParams.size,
            total: searchParams.totalSize,
            onChange(page, pageSize) {
                searchParams.page = page
                searchParams.size = pageSize
                reFetch()
            },
        }">
            <template #bodyCell="{ column, record }">
                <template v-if="column.key === 'executeTime'">
                  {{ record[column.key] }} 
                   <!-- {{ dayjs(record[column.key]).format('YYYY-MM-DD - HH:mm:ss') }} -->
                </template>

                <template v-if="column.key === 'isDisabled'">
                    <span>{{ record.isDisabled ? '禁用' : '启用' }}</span>
                </template>

                <template v-if="column.key === 'operator'">
                    <Button type="link" @click="handleOpenUpdate(record as ITimePlan)">
                        编辑
                    </Button>
                    <Popconfirm title="你确定要删除这个用例吗？（此操作不可逆！）" @confirm="handleDelete(record as ITimePlan)">
                        <Button type="link" danger><span text-red>删除</span></Button>
                    </Popconfirm>
                </template>
            </template>
        </Table>
        <div flex items-center>
            <Button type="link" @click="AddTestPlan">+ 新增计划</Button>
        </div>
        <!-- 编辑 -->
        <Modal v-model:open="openUpdate" title="编辑用例" @ok="handleUpdate">
            <div style="">
                <Form ref="formUpdateRef" :model="oneUpdateValue" :rules="formRules" layout="inline"
                    :label-col="{ span: 8 }" :wrapper-col="{ span: 16 }" autocomplete="off" style="
            display: flex;
            flex-direction: column;
            justify-content: space-around;
          ">
                    <Form.Item label="名称：" name="name">
                        <Input v-model:value="oneUpdateValue.name" placeholder="请输入名称" style="width: 200px" />
                    </Form.Item>

                    <Form.Item label="用例类型：" name="testType">
                        <Dropdown>
                            <Button type="link">
                                {{
                                    oneUpdateValue.testType
                                    ? oneUpdateValue.testType
                                    : '请选择用例类型'
                                }}
                            </Button>
                            <template #overlay>
                                <Menu>
                                    <Menu.Item v-for="item in testTypeList" :key="item.id">
                                        <Button type="text" size="small" @click="handleUpdateSelectTypeList(item.type)">
                                            {{ item.type }}
                                        </Button>
                                    </Menu.Item>
                                </Menu>
                            </template>
                        </Dropdown>
                    </Form.Item>

                    <Form.Item label="模块选择" name="moduleId">
                        <Select v-model:value="oneUpdateValue.moduleId" @focus="handleUpdateFocus(0)"
                            @change="handleUpdateModuleChange" placeholder="请选择模块" style="width: 200px">
                            <Select.Option v-for="{ id, name } in modules" :key="id" :value="id">
                                <Tooltip :title="name">{{ name }}</Tooltip>
                            </Select.Option>
                        </Select>
                    </Form.Item>

                    <Form.Item label="用例ID：" name="caseId">
                        <Select v-model:value="oneUpdateValue.caseId" @focus="handleUpdateFocus(1)"
                            @change="handleUpdateCaseIDChange" placeholder="请选择用例ID" style="width: 200px">
                            <Select.Option v-for="{ id, name } in caseIds" :key="id" :value="id">
                                <Tooltip :title="name">{{ name }}</Tooltip>
                            </Select.Option>
                        </Select>

                    </Form.Item>

                    <Form.Item label="环境选择" name="environmentId">
                        <Select v-model:value="oneUpdateValue.environmentId" @change="handleChange">
                            <Select.Option v-for="{ id, name, description } in globalConfigStore.config.environmentDatas"
                                :key="id" :value="id">
                                <Tooltip :title="description">{{ name }}</Tooltip>
                            </Select.Option>
                        </Select>
                    </Form.Item>
                    <Form.Item label="每天执行：" name="executeInterval">
                        <Checkbox v-model:checked="oneUpdateValue.executeInterval"
                            @change="handleUpdateExecuteIntervalChange"></Checkbox>
                    </Form.Item>
                    <Form.Item label="执行时间：" name="executeTime" style="margin-right: 0;">
                        <TimePicker v-if="oneUpdateValue.executeInterval" v-model:value="oneUpdateValue.executeTime"
                            value-format="HH:mm:ss" />
                        <DatePicker v-else v-model:value="oneUpdateValue.executeTime" show-time
                            value-format="YYYY-MM-DD HH:mm:ss" type="date" />
                    </Form.Item>

                    <Form.Item label="状态：" name="isDisabled">
                        <span>{{
                            !oneUpdateValue.isDisabled ? '禁用' : '激活'
                        }}&nbsp;&nbsp;</span>
                        <Button type="primary" size="small" @click="toggleDisabledStatus">{{
                            oneUpdateValue.isDisabled ? '禁用' : '启用'
                        }}</Button>
                    </Form.Item>

                </Form>
            </div>
        </Modal>
        <!-- 新增 -->
        <Modal v-model:open="openAdd" title="新增用例" @ok="handleAdd" @cancel="cancelClick">
            <div style="">
                <Form ref="formAddRef" :model="oneAddValue" :rules="formRules" layout="inline" :label-col="{ span: 8 }"
                    :wrapper-col="{ span: 16 }" autocomplete="off" style="
            display: flex;
            flex-direction: column;
            justify-content: space-around;
          ">
                    <Form.Item label="名称：" name="name">
                        <Input v-model:value="oneAddValue.name" placeholder="请输入名称" style="width: 200px" />
                    </Form.Item>
                    <Form.Item label="用例类型：" name="testType">
                        <Dropdown>
                            <Button type="link">
                                {{
                                    oneAddValue.testType ? oneAddValue.testType : '请选择用例类型'
                                }}
                            </Button>
                            <template #overlay>
                                <Menu>
                                    <Menu.Item v-for="item in testTypeList" :key="item.id">
                                        <div @click="handleSelectTypeList(item.type)">
                                            {{ item.type }}
                                        </div>
                                    </Menu.Item>
                                </Menu>
                            </template>
                        </Dropdown>
                    </Form.Item>

                    <Form.Item label="模块选择" name="moduleId">
                        <Select v-model:value="oneAddValue.moduleId" @focus="handleFocus(0)" @change="handleModuleChange"
                            placeholder="请选择模块" style="width: 200px">
                            <Select.Option v-for="{ id, name } in modules" :key="id" :value="id">
                                <Tooltip :title="name">{{ name }}</Tooltip>
                            </Select.Option>
                        </Select>
                    </Form.Item>

                    <Form.Item label="用例ID：" name="caseId">
                        <Select v-model:value="oneAddValue.caseId" @focus="handleFocus(1)" @change="handleCaseIDChange"
                            placeholder="请选择用例ID" style="width: 200px">
                            <Select.Option v-for="{ id, name } in caseIds" :key="id" :value="id">
                                <Tooltip :title="name">{{ name }}</Tooltip>
                            </Select.Option>
                        </Select>
                    </Form.Item>

                    <Form.Item label="环境选择" name="environmentId">
                        <Select v-model:value="oneAddValue.environmentId" @change="handleChange" placeholder="请选择环境"
                            style="width: 200px">
                            <Select.Option v-for="{ id, name, description } in globalConfigStore.config.environmentDatas"
                                :key="id" :value="id">
                                <Tooltip :title="description">{{ name }}</Tooltip>
                            </Select.Option>
                        </Select>
                    </Form.Item>
                    <Form.Item label="每天执行：" name="executeInterval">
                        <Checkbox v-model:checked="oneAddValue.executeInterval" @change="handleAddExecuteIntervalChange">
                        </Checkbox>
                    </Form.Item>
                    <Form.Item label="执行时间：" name="executeTime">
                        <TimePicker v-if="oneAddValue.executeInterval" v-model:value="oneAddValue.executeTime"
                            value-format="HH:mm:ss" />
                        <DatePicker v-else v-model:value="oneAddValue.executeTime" show-time
                            value-format="YYYY-MM-DD HH:mm:ss" type="date" />
                    </Form.Item>

                    <Form.Item label="状态：" name="isDisabled">
                        <span>{{ !oneAddValue.isDisabled ? '禁用' : '激活' }}&nbsp;&nbsp;</span>
                        <Button type="primary" size="small" @click="toggleADDDisabledStatus">{{ oneAddValue.isDisabled ?
                            '禁用' : '启用'
                        }}</Button>
                    </Form.Item>
                </Form>
            </div>
        </Modal>
    </div>
</template>

<style scoped>
.ant-form-item {
    margin-bottom: 20px;
}
</style>